package cn.com.dstz.base.action;

import java.io.IOException;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import net.sf.json.JSONObject;

import org.apache.commons.lang.StringUtils;
import org.apache.struts2.ServletActionContext;
import org.hibernate.type.Type;

import cn.com.dstz.admin.constants.Constants;
import cn.com.dstz.utils.DataBaseUtils;
import cn.com.dstz.utils.DateUtils;
import cn.com.dstz.utils.FillNameQuery;
import cn.com.dstz.utils.NumberUtils;
import cn.com.dstz.utils.Pagination;
import cn.com.dstz.utils.RequestUtils;
import cn.com.dstz.web.page.Page;

import com.hd.base.service.BaseService;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;

/**
 * 提供一些公用的方法供其他Action使用
 * @author 叶装装
 */
public class BaseAction extends ActionSupport{

	private static final long serialVersionUID = 1L;
	protected BaseService baseService;

	protected void setSessionAttr( String key, Object value ){
		Map<String , Object> session = ActionContext.getContext().getSession();
		
		session.put(key, value);
	}
	protected void responseToJsonObject( Object info ){
		ajaxResponse( JSONObject.fromObject( info ));
		
	}
	
	protected void ajaxResponse(Object info) {
		
		HttpServletResponse response = ServletActionContext.getResponse();
		response.setContentType("text/xml;charset=UTF-8");
		response.setHeader("Cache-Control", "no-cache");
		PrintWriter out =null;
		try {
			out = response.getWriter();
			out.write( info.toString( ) );
			out.close();
		} catch (IOException e) {
			e.printStackTrace();
		}finally{
			try {
				if(out!=null){
					out.close();
				}
			} catch (Exception e) {
			}
		}
	}
	protected void outprintResponse(Object info) {
		
		HttpServletResponse response = ServletActionContext.getResponse();
		response.setContentType("text/html;charset=UTF-8");
		response.setHeader("Cache-Control", "no-cache");
		PrintWriter out =null;
		try {
			out = response.getWriter();
			out.print( info.toString( ) );
			out.close();
		} catch (IOException e) {
			e.printStackTrace();
		}finally{
			try {
				if(out!=null){
					out.close();
				}
			} catch (Exception e) {
			}
		}
	}
	
	/**
	 * aliasMap 别名的Map
	 */
	protected Map< String, Object > paginationBySQL( String SQL, String originalCountSQL, Map< String, Object > valueMap, String datekey, Map< String, Type > aliasMap ){
		
		Map< String, String > sqlMap = this.getCountSQLAndFindSQL( SQL, originalCountSQL, valueMap, datekey );
		
		String countSQL = sqlMap.get( "count" );
		String findSQL = sqlMap.get( "find" );

		// 获取每页显示的数据和当前页
		int rp = NumberUtils.getInt( this.getParameter( "rows" ), 10 );
		int currentPage =NumberUtils.getInt( this.getParameter( "page" ), 1 );
		
		int count = baseService.countBySQL( countSQL, valueMap );

		Page page = new Page( count, rp, currentPage );
		
		Map< String, Object > resultMap = new HashMap< String, Object >( );
		resultMap.put ( "total",page.getTotalSize ( ) );		
		
		List<Map< String, Object>> list = baseService.queryList( findSQL, page.getBeginsize( ), rp, valueMap, aliasMap );
		
		resultMap.put ( "rows", list );
		
		return resultMap;
		
	}
	
	protected Map< String, Object > paginationBySQL( String SQL, String originalCountSQL, Map< String, Object > valueMap, String datekey ){
		return paginationBySQL( SQL, originalCountSQL, valueMap, datekey, null );
	}
	
	@SuppressWarnings( "unchecked" )
	protected <T> T getEntityInSession(String key) {
		
		Map<String , Object> session = ActionContext.getContext().getSession();
		
        return (T) session.get(key);
        
	}
	
	protected void addLog( int success, String type, int saveOrUpdate, Object desc, String option ){
		if( success <= 0 ){
			return;
		}
		
		if( StringUtils.isBlank( option )){
			option = saveOrUpdate == 0 ? "【添加】->" : ( saveOrUpdate == 1 ? "【编辑】->" : "【删除】->" );
		}
		
		Map< String, Object > admin = this.getEntityInSession( cn.com.dstz.web.constants.Constants.ADMIN_IN_SESSION );
		
		String name = Constants.functionMap.get( type );
		String datetime = DateUtils.getCurrentTime( );
		String ip = RequestUtils.getIpAddr( getRequest( ) );
		
		baseService.save( "dstz_log", DataBaseUtils.getInsertData( new String[]{
				"name", "description", "ip", "datetime", "user", "userid"
		}, new Object[]{
				name, option + "【" + desc + "】", ip, datetime, admin.get( "username" ), admin.get( "id" )
		} ) );
		
	}
	
	/**
	 * @param success			是否成功的标识,只有成功才保持
	 * @param type				日志类型
	 * @param saveOrUpdate	0 添加, 1 编辑, 2 删除
	 * @param desc				描述
	 */
	protected void addLog( int success, String type, int saveOrUpdate, Object desc ){
		addLog( success, type, saveOrUpdate, desc, null );
	}
	
	
	/**
	 * 封装分页数据处理，返回JSON数据
	 * @param HQL				HQL语句
	 * @param originalCountHQL   使用自己的统计语句
	 * @param firstResult
	 * @param maxResult
	 * @param valueMap
	 */
	protected Map< String, Object > pagination( String HQL, String originalCountHQL, Map< String, Object > valueMap ){
		
		String queryParams = getQueryParameters( valueMap, "" );
		
		HQL += queryParams;
		
		String countHQL = Pagination.getCountHQL( HQL );
		
		if( StringUtils.isNotBlank( originalCountHQL )){
			countHQL = originalCountHQL;
		}
		
		countHQL += queryParams;
		
		
		// 获取每页显示的数据和当前页
		int rp = NumberUtils.getInt( this.getParameter( "rp" ), 10 );
		int currentPage =NumberUtils.getInt( this.getParameter( "page" ), 1 );
		
		Long count = baseService.count( countHQL, valueMap );
		Page page = new Page( Pagination.convertLongToInt( count ), rp, currentPage );
		
		
		Map< String, Object > resultMap = new HashMap< String, Object >( );
		resultMap.put ( "total",page.getTotalSize ( ) );		
		
		HQL += getSort( );
		
		List< Object > list = baseService.find( HQL, valueMap, page.getBeginsize( ), rp );
	
		List< Map< String, Object >> dataList = new ArrayList< Map< String, Object >> ( list.size( ) );
		
		for( Object obj : list ){
			dataList.add( Pagination.reflect( obj ) );
		}
		
		resultMap.put ( "rows", dataList );
		
		return resultMap;
		
	}
	
	protected String getSort(  ){
		String sort = getParameter( "sort" );
		String order = getParameter ( "order" );
		if( StringUtils.isNotBlank ( sort ) && StringUtils.isNotBlank ( order )){
			return " order by " + sort + " " + order ;
		}
		return "";
	}
	
	@SuppressWarnings( "unchecked" )
	protected String getQueryParameters( Map< String, Object > valueMap, String datekey ){
		HttpServletRequest request =  ServletActionContext.getRequest( );
		Enumeration <  String > params = request.getParameterNames( );
		
		StringBuilder sql = new StringBuilder( );
		

		while( params.hasMoreElements ( ) ){
			String param = params.nextElement ( ); // 获取参数名称
			
			String value =   getParameter ( param ) ; // 获取值

			// 过滤page和rows,order,sort, 可以不要这句
			if( "page".equals ( param ) || "rows".equals ( param ) || "order".equals ( param ) || "sort".equals ( param )){
				continue;
			}
			// 如果为空，继续循环, 或者是提交上来的数据位undefined
			if( StringUtils.isBlank ( param ) || StringUtils.isBlank ( value ) || "undefined".equals( value )){
				continue;
			}
			
			value = decode( value ,  "UTF-8" );
			
			
			if( param.startsWith ( "S_" )){
				param = getParameter ( param, "S_" ); 
				sql.append ( " and " );
				sql.append ( param );
				sql.append ( " =:" );
				
				String processParam = Pagination.processQueryParam( param );
				sql.append( processParam );
				valueMap.put( processParam, value );
				
				
			}else if( param.startsWith ( "L_" )){
				param = getParameter ( param, "L_" ); 
				sql.append ( " and " );
				sql.append ( param );
				sql.append ( " like :" );
				
				String processParam = Pagination.processQueryParam( param );
				sql.append( processParam );
				valueMap.put( processParam, "%" + value + "%" );
				
			}
		}
		
		// 时间范围的
		sql.append( getDateRangeKey( getRequest(), datekey ) );
		
		
		
		return sql.toString( );
		
	}
	
	protected String getDateRangeKey( HttpServletRequest request, String datekey ){
		
		if( StringUtils.isBlank ( datekey )){
			return "";
		}
		
		String begindate = request.getParameter ( "begindate" );
		String enddate = request.getParameter ( "enddate" );
		
		StringBuilder sql = new StringBuilder( );
		
		if( StringUtils.isNotBlank( begindate ) && StringUtils.isNotBlank( enddate )){
			sql.append( " and " );
			sql.append( datekey );
			sql.append( " between '" );
			sql.append( begindate );
			sql.append( "'" );
			sql.append( " and '" );
			sql.append( enddate );
			sql.append( "'" );
		}
		return sql.toString ( );
		
	}
	
	protected String getParameterByDecode( String key ){
		HttpServletRequest request = getRequest( );
		String value = request.getParameter( key );
		
		if( StringUtils.isNotBlank( value )){
			value = decode( value );
		}
		
		return value;
	}
	
	protected String getParameter( String key ){
		HttpServletRequest request = ServletActionContext.getRequest( );
		return request.getParameter( key );
	}
	
	protected  String getParameter( String param, String prefix ){
		
		if( StringUtils.isBlank ( param ) || StringUtils.isBlank ( prefix )){
			return param;
		}
		
		return param.substring ( prefix.length ( ), param.length ( ) );
	}
	
	public static String decode( String s, String charset ){
		try {
			return URLDecoder.decode(s,  charset );
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		return s;
	}
	
	/**
	 * 以UTF-8 解码
	 * @param s
	 * @return
	 */
	public static String decode(String s) {
		try {
			return URLDecoder.decode(s, "UTF-8");
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		return s;
	}
	
	public String decodeString( String str, String charset ){
		
		if( str == null ){
			return "";
		}
		
		try {
			str = new String( str.getBytes( "ISO8859-1" ),  charset );
		} catch ( UnsupportedEncodingException e ) {
			e.printStackTrace();
		}
		
		return str;
		
	}
	public  String decodeString( String str ){
		
		if( str == null ){
			return "";
		}
		
		try {
			str = new String( str.getBytes( "ISO8859-1" ), "GBK" );
		} catch ( UnsupportedEncodingException e ) {
			e.printStackTrace();
		}
		
		return str;
		
	}
	
	protected HttpSession getSession( ){
		HttpServletRequest request = getRequest( );
		HttpSession session = request.getSession( false );
		if( session == null ){
			session = request.getSession( true );
		}
		return session;
	}
	
	protected HttpServletRequest getRequest( ){
		return ServletActionContext.getRequest( );
	}
	
	protected void alertMsg( String alertMsg ){
		if( StringUtils.isBlank( alertMsg )){
			alertMsg = "无法获取对应的数据!";
		}
		getRequest( ).setAttribute( "alertMsg", alertMsg );
	}
	
	private Map< String, String > getCountSQLAndFindSQL( String SQL,  String originalCountSQL, Map< String, Object > valueMap, String datekey ){
		
		String queryParams = getQueryParameters( valueMap, datekey ); // 获取参数
		
		StringBuffer findSQLBuffer = new StringBuffer( );
		StringBuffer countSQLBuffer = new StringBuffer( );
		
		String countSQL =  Pagination.getCountSQL( SQL ); // 去除group by , order by 是在getSort()方法里追加的，所以不必进行order by判断
		// 如果是使用自定义的countSQL
		if( StringUtils.isNotBlank( originalCountSQL )){
			countSQL = originalCountSQL;
		}
		
		countSQLBuffer.append( countSQL );
		countSQLBuffer.append( queryParams ); // 添加参数
		
		
		int groupByIndex = SQL.lastIndexOf( "group by" ); // 查看是否有group by
		
		String groupBySQL = "";
		// 有的话， 进行截取
		if( groupByIndex != -1 ){
			groupBySQL = SQL.substring( groupByIndex, SQL.length( ) );
			SQL = SQL.substring( 0, groupByIndex );
		}
		findSQLBuffer.append( SQL );
		findSQLBuffer.append( queryParams ); // 绑定参数
		findSQLBuffer.append( " " );			
		findSQLBuffer.append( groupBySQL ); // 绑定group by
		findSQLBuffer.append( getSort( ) );	// 绑定排序
	
		Map< String, String > sqlMap = new HashMap< String, String >( );
		sqlMap.put( "count", countSQLBuffer.toString( ) );
		sqlMap.put( "find", findSQLBuffer.toString( ) );
		
		return sqlMap;
		
	}
	
	
	public BaseService getBaseService( ) {
		return baseService;
	}

	public void setBaseService( BaseService baseService ) {
		this.baseService = baseService;
	}
	
	protected int countManagerGroup( ){
		String sql = "select count(*) as a from dstzgroup g, dstz_group_type t where g.id = t.groupid and t.ismanager=:ismanager and t.level > :level";
		int count = baseService.countBySQL( sql, FillNameQuery.fillValue( sql, 1, 0 ) );
		return count;
	}
	
	
	
}
